home *** CD-ROM | disk | FTP | other *** search
- /* -------------------------------------------------------------------------- */
- /* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY */
- /* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE */
- /* IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR */
- /* PURPOSE. */
- /* */
- /* You have a royalty-free right to use, modify, reproduce and */
- /* distribute the Sample Files (and/or any modified version) in */
- /* any way you find useful, provided that you agree that */
- /* Creative has no warranty obligations or liability for any Sample Files. */
- /*----------------------------------------------------------------------------*/
-
-
- /* ---------------------------------------------------------------------------
- Program: Sound Blaster 16 MIDI Utilities
- Filename: MIDIUTIL.C
- Author: Scott E. Sindorf
- Language: Borland C
- Date: 30 Jun 93
-
- Copyright (c) 1993-1996 Creative Labs, Inc.
- -----------------------------------------------------------------------------*/
-
- #include <conio.h>
- #include "midiutil.h"
- #include "sbcutils.h"
-
- extern BLASTREC blastInfo;
-
- int MIDIType = MPU401; // MIDI type to use flag
-
- /************************************************************************
- * WRITE_MPU401_CMD: sends a command to the MPU401 port.
- *
- * Input: command - command byte
- *
- * Output: none
- ************************************************************************/
- void Write_MPU401_Cmd(unsigned char command)
- {
- // check write status
- while((inp(blastInfo.midiPort + 1) & MPU401_OK2WR));
-
- outp(blastInfo.midiPort + 1, command);
- }
-
- /************************************************************************
- * WRITE_MPU401_DATA: sends a data byte to the MPU401 port.
- *
- * Input: data - data byte
- *
- * Output: none
- ************************************************************************/
- void Write_MPU401_Data(unsigned char data)
- {
- // check write status
- while((inp(blastInfo.midiPort + 1) & MPU401_OK2WR));
-
- outp(blastInfo.midiPort, data);
- }
-
- /************************************************************************
- * WRITE_SBMIDI_DATA: sends a byte to the Sound Blaster MIDI port.
- *
- * Input: data - data byte
- *
- * Output: none
- ************************************************************************/
- void Write_SBMIDI_Data(unsigned char data)
- {
- // wait for write buffer ready
- while(inp(blastInfo.baseAddr + DSP_WR_ST) & MSB);
- // send MIDI write command
- outp(blastInfo.baseAddr + DSP_WR, MIDI_OUT_P);
-
- // wait for write buffer ready
- while(inp(blastInfo.baseAddr + DSP_WR_ST) & MSB);
- // send MIDI data byte
- outp(blastInfo.baseAddr + DSP_WR, data);
- }
-
- /************************************************************************
- * READ_MPU401_DATA: reads a byte from the MPU401 port.
- *
- * Input: none
- *
- * Output: data byte
- ************************************************************************/
- unsigned char Read_MPU401_Data(void)
- {
- // check read status
- while((inp(blastInfo.midiPort + 1) & MPU401_OK2RD));
-
- return(inp(blastInfo.midiPort));
- }
-
- /************************************************************************
- * READ_SBMIDI_DATA: reads a byte from the Sound Blaster MIDI port.
- *
- * Input: none
- *
- * Output: data - data byte
- ************************************************************************/
- unsigned char Read_SBMIDI_Data(void)
- {
- unsigned char data;
-
- // wait for write buffer ready
- while(inp(blastInfo.baseAddr + DSP_WR_ST) & MSB);
- // send MIDI read command
- outp(blastInfo.baseAddr + DSP_WR, MIDI_IN_P);
- // wait for read buffer ready
- while(!(inp(blastInfo.baseAddr + DSP_RD_ST) & MSB));
- // read MIDI data byte
- data = inp(blastInfo.baseAddr + DSP_RD);
- // wait for write buffer ready
- while(inp(blastInfo.baseAddr + DSP_WR_ST) & MSB);
- // stop MIDI read
- outp(blastInfo.baseAddr + DSP_WR, MIDI_IN_P);
- return(data);
- }
-
- /************************************************************************
- * SEND_MIDI_MESSAGE: Sends a MIDI message to port
- *
- * Input: message - MIDI message to send
- * size - length of message
- *
- * Output: none
- ************************************************************************/
- void Send_MIDI_Message(char far *message, int size)
- {
- int i;
-
- if(MIDIType == MPU401)
- for(i = 0; i < size; i++)
- Write_MPU401_Data(message[i]);
- else
- for(i = 0; i < size; i++)
- Write_SBMIDI_Data(message[i]);
- }
-
- /************************************************************************
- * SET_MIDI_VOL: Sets the global volume on the requested channel
- *
- * Input: channel - set volume on this channel (1 to 16)
- * volume - set channel to this volume (0 to 127)
- *
- * Output: none
- *
- * note: if inputs are out of range then no action occurs
- ************************************************************************/
- void Set_MIDI_Vol(char channel, char volume)
- {
- char message[3];
-
- if((channel <= 16) && (channel > 0))
- if(volume >= 0)
- {
- message[0] = 0xb0 + channel - 1; // set channel
- message[1] = 7; // set global volume command
- message[2] = volume; // set volume level
- Send_MIDI_Message(message, 3);
- }
- }
-
- /************************************************************************
- * SET_MIDI_NOTES_OFF: Turns off all notes on the given channel
- *
- * Input: channel - turns off all notes on this channel (1 to 16)
- *
- * Output: none
- *
- * note: if channel is out of range then no action occurs
- ************************************************************************/
- void Set_MIDI_Notes_Off(char channel)
- {
- char message[3];
-
- if((channel <= 16) && (channel > 0))
- {
- message[0] = 0xb0 + channel - 1; // set channel
- message[1] = 0x7b; // clear all notes command
- message[2] = 0;
- Send_MIDI_Message(message, 3);
- }
- }
-
- /************************************************************************
- * SET_MIDI_PITCH_BEND: Sets pitch bend (0 = OFF).
- *
- * Input: channel - sets pitch bend on this channel (1 to 16)
- * bend - pitch bend value (-8192 to 8191)
- *
- * Output: none
- *
- * note: if inputs are out of range then no action occurs
- ************************************************************************/
- void Set_MIDI_Pitch_Bend(char channel, int range)
- {
- char message[3];
-
- if((channel <= 16) && (channel > 0))
- if((range >= -8192) && (range < 8192))
- {
- range += 8192;
- message[0] = 0xe0 + channel - 1; // set channel
- message[1] = range >> 7; // set pitch bend (MSB)
- message[2] = range & 0x7f; // set pitch bend (LSB)
- Send_MIDI_Message(message, 3);
- }
- }
-
- /************************************************************************
- * RESET_MPU401: resets the MPU401 port.
- *
- * Input: none
- *
- * Output: result - (0 = OK, -1 = ERROR)
- *
- * note: Error will occur if UART mode is not turned off first.
- ************************************************************************/
- int Reset_MPU401(void)
- {
- int i = 100;
-
- Write_MPU401_Cmd(MPU401_RESET); // send reset command
- while((i > 0) && (Read_MPU401_Data() != MPU401_CMDOK))
- i--; // offer timeout instead of lockup
-
- if(i == 0)
- return(ERROR);
- else
- return(OK);
- }
-
- /************************************************************************
- * SET_UART_MODE: puts the MPU401 port in UART mode.
- *
- * Input: state - ON or OFF (Reset will return error if UART mode is on
- * when reset occurs)
- *
- * Output: result - (0 = OK, -1 = ERROR)
- ************************************************************************/
- int Set_UART_Mode(int state)
- {
- int i = 100;
-
- if(state == ON)
- {
- Write_MPU401_Cmd(MPU401_UART); // turn on UART mode
- while((i > 0) && (Read_MPU401_Data() != MPU401_CMDOK))
- i--; // offer timeout instead of lockup
- }
- else
- Write_MPU401_Cmd(MPU401_RESET); // turn off UART mode
-
- if(i == 0)
- return(ERROR);
- else
- return(OK);
- }
-
- /************************************************************************
- * DETECT_MIDI: Detects the presence of the MPU-401 port or the SBMIDI
- * port.
- *
- * Input: none
- *
- * Output: result - (0 = OK if found, -1 = ERROR if not found)
- ************************************************************************/
- int Detect_MIDI(void)
- {
- unsigned char status;
- int result = ERROR;
-
- if(MIDIType == MPU401)
- {
- // check write status
- status = inp(blastInfo.midiPort + 1);
-
- if(!(status & MPU401_OK2WR))
- {
- Set_UART_Mode(OFF); // just in case it was left on
- result = Reset_MPU401(); // does reset work?
- }
- }
- else
- result = DSPReset(); // reset the DSP
-
- return(result);
- }
-
- /************************************************************************
- * INIT_MIDI: Initializes the MIDI port. If MPU-401 port then reset
- * the port and select UART mode. For either MPU-401 or
- * SBMIDI ports set all master volumes to 100, turn off all
- * notes, and reset all pitch bends.
- *
- * Input: none
- *
- * Output: result - (0 = OK, -1 = ERROR)
- ************************************************************************/
- int Init_MIDI(void)
- {
- int i;
-
- if(MIDIType == MPU401)
- {
- if(Reset_MPU401() == ERROR) // reset port
- return(ERROR);
-
- if(Set_UART_Mode(ON) == ERROR) // set UART mode
- return(ERROR);
- }
-
- for(i = 1; i <= 16; i++)
- {
- Set_MIDI_Vol(i, 100); // set channel volume
- Set_MIDI_Notes_Off(i); // turn off all notes
- Set_MIDI_Pitch_Bend(i, 0); // reset pitch bends
- }
- return(OK);
- }
-
- /************************************************************************
- * EXIT_MIDI: Terminates MIDI driver by turning off all notes (and
- * turning off UART mode if using MPU-401 port).
- *
- * Input: none
- *
- * Output: none
- ************************************************************************/
- void Exit_MIDI(void)
- {
- int i;
-
- for(i = 0; i < 16; i++)
- Set_MIDI_Notes_Off(i); // turn off all notes
-
- if(MIDIType == MPU401)
- Set_UART_Mode(OFF); // exit UART mode
- }
-